/*****************************************************************************
	SNEGA UTILITIES 0.7a
	Copyright (C) 2009, Xiaohan Tian (snega0223)
	
	http://code.google.com/p/snega-utilities/
	
	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License(LGPL) as
	published by the Free Software Foundation, either version 3 of the 
	License, or(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.
	
	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/

package org.sng.util.web;

public class ParserUtilities {
	
	/*
	 * NOTE: This function is copied from Freemaker source
	 * */
	public static StringBuffer EscapedCharsToNormal(String s)
	{
		
		int idx = s.indexOf('\\');
        if (idx == -1)
            return new StringBuffer(s);

        int lidx = s.length() - 1;
        int bidx = 0;
        StringBuffer buf = new StringBuffer(lidx);
        try
		{
        	do {
	            buf.append(s.substring(bidx, idx));
	            if (idx >= lidx) {
	                throw new Exception("The last character of string literal is backslash");
	            }
	            char c = s.charAt(idx + 1);
	            switch (c) {
	                case '"':
	                    buf.append('"');
	                    bidx = idx + 2;
	                    break;
	                case '\'':
	                    buf.append('\'');
	                    bidx = idx + 2;
	                    break;
	                case '\\':
	                    buf.append('\\');
	                    bidx = idx + 2;
	                    break;
	                case 'n':
	                    buf.append('\n');
	                    bidx = idx + 2;
	                    break;
	                case 'r':
	                    buf.append('\r');
	                    bidx = idx + 2;
	                    break;
	                case 't':
	                    buf.append('\t');
	                    bidx = idx + 2;
	                    break;
	                case 'f':
	                    buf.append('\f');
	                    bidx = idx + 2;
	                    break;
	                case 'b':
	                    buf.append('\b');
	                    bidx = idx + 2;
	                    break;
	                case 'g':
	                    buf.append('>');
	                    bidx = idx + 2;
	                    break;
	                case 'l':
	                    buf.append('<');
	                    bidx = idx + 2;
	                    break;
	                case 'a':
	                    buf.append('&');
	                    bidx = idx + 2;
	                    break;
	                case 'x': {
	                    idx += 2;
	                    int x = idx;
	                    int y = 0;
	                    int z = lidx > idx + 3 ? idx + 3 : lidx;
	                    while (idx <= z) {
	                        char b = s.charAt(idx);
	                        if (b >= '0' && b <= '9') {
	                            y <<= 4;
	                            y += b - '0';
	                        } else if (b >= 'a' && b <= 'f') {
	                            y <<= 4;
	                            y += b - 'a' + 10;
	                        } else if (b >= 'A' && b <= 'F') {
	                            y <<= 4;
	                            y += b - 'A' + 10;
	                        } else {
	                            break;
	                        }
	                        idx++;
	                    }
	                    if (x < idx) {
	                        buf.append((char) y);
	                    } else {
	                        throw new Exception("Invalid \\x escape in a string literal");
	                    }
	                    bidx = idx;
	                    break;
	                }
	                default:
	                    throw new Exception("Invalid escape sequence (\\" + c + ") in a string literal");
	            }
	            idx = s.indexOf('\\', bidx);
	        } while (idx != -1);
		}
        catch (Exception e)
        {
        	e.printStackTrace();
        }
        buf.append(s.substring(bidx));

        return buf;
	}

}
